#include<bits/stdc++.h>
#include<windows.h>
using namespace std;

const int blockSize = 100; // 定义每个逻辑块的大小为100

void createDiskFile() {
    // 创建一个名为"hd.txt"的磁盘文件
    ofstream diskFile("hd.txt", ios::binary);
    for(int i=1;i<=10;i++){
        // 生成一个逻辑块，内容为"Block(i): message..."
        string block="Block("+to_string(i)+"): message...";
        if (block.size() < blockSize) {
            // 如果逻辑块的大小小于100，就在其后面补充'\0'直到其大小为100
            block.append(blockSize - block.size(), '\0');
        }
        // 将逻辑块写入磁盘文件
        diskFile.write(block.data(), block.size());
    }
    // 关闭磁盘文件
    diskFile.close();
}

HANDLE createNamedPipe() {
    // 创建一个名为"diskPipe"的命名管道
    HANDLE hPipe=CreateNamedPipe(
        TEXT("\\\\.\\Pipe\\diskPipe"),
        PIPE_ACCESS_DUPLEX,
        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
        1,
        1024,
        1024,
        0,
        NULL
    );
    // 如果创建管道失败，输出错误信息并退出程序
    if(hPipe==INVALID_HANDLE_VALUE){
        cerr<<"Create pipe failed: "<<GetLastError()<<endl;
        system("pause");
        exit(0);
    }
    // 返回管道句柄
    return hPipe;
}

string readBlockFromDisk(int blockNum) {
    // 打开磁盘文件
    ifstream diskFile("hd.txt");
    // 定位到指定的磁盘块的起始位置
    for(int i = 0; i < (blockNum-1) * 100; ++i) {
        diskFile.ignore();
    }
    // 创建一个大小为101的字符串，用于存储磁盘块的内容
    string contents(101, '\0');
    // 读取磁盘块的内容
    diskFile.read(&contents[0], 100);
    // 关闭磁盘文件
    diskFile.close();
    // 返回磁盘块的内容
    return contents;
}

void handleClientConnection(HANDLE hPipe) {
    // 创建一个大小为101的字符向量，用于存储从管道中读取的数据
    vector<char> buffer(101, '\0');
    DWORD dwNumberOfBytesRead=0;
    DWORD dwNumberOfBytesWritten=0;
    // 循环读取客户端发送的请求
    for(int i=0;i<10;i++){
        // 读取请求
        if (!ReadFile(hPipe, buffer.data(), buffer.size(), &dwNumberOfBytesRead, NULL)) {
            break;
        }
        // 将请求转换为磁盘块号
        int blockNum=stoi(string(buffer.begin(), buffer.end()));
        // 清空缓冲区
        buffer.assign(101, '\0');
        // 读取指定的磁盘块的内容
        string contents = readBlockFromDisk(blockNum);
        // 将磁盘块的内容发送给客户端
        if (!WriteFile(hPipe, contents.data(), contents.size(), &dwNumberOfBytesWritten, NULL)) {
            break;
        }
    }
}

int main(){
    // 创建磁盘文件
    createDiskFile();
    // 创建命名管道
    HANDLE hPipe = createNamedPipe();

    // 等待客户端连接管道
    if(ConnectNamedPipe(hPipe,NULL)){
        // 处理客户端的连接请求
        handleClientConnection(hPipe);
    }
    // 清空管道的缓冲区
    FlushFileBuffers(hPipe);
    // 断开管道的连接
    DisconnectNamedPipe(hPipe);
    // 关闭管道
    CloseHandle(hPipe);
    // 暂停程序，等待用户输入
    system("pause");
    return 0;
}